package com.zl.shirodemo.config;

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.BearerToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.zl.shirodemo.entity.Permission;
import com.zl.shirodemo.entity.SysUser;
import com.zl.shirodemo.entity.UserRole;
import com.zl.shirodemo.mapper.RolePermissionMapper;
import com.zl.shirodemo.mapper.SysUserMapper;
import com.zl.shirodemo.mapper.SysUserRoleMapper;
import com.zl.shirodemo.util.JWTUtil;

@Component
public class JWTRealm extends AuthorizingRealm {
    
    /**
     * 是否开启认证缓存，默认shiro是不开启的，我们这里覆盖变量，自己控制是否开启
     */
    @Value("${shiro.JWTauthenticationCachingEnabled}")
    protected Boolean authenticationCachingEnabled;
    
    @Autowired
    private JWTUtil jwtUtil;
    
    @Autowired
    private SysUserMapper sysUserMapper;
    
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    
    //使用的DefaultFilter.authcBearer 作为token支持，所以这里需要用BearerToken
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof BearerToken;
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String principal = (String)principals.getPrimaryPrincipal();
        int userId = jwtUtil.getUserIdByToken(principal);
        List<UserRole> userRoles = sysUserRoleMapper.selectRolesByUserId(userId);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        userRoles.forEach(userRole -> {
            simpleAuthorizationInfo.addRole(userRole.getRoleName());
        });
        
        List<Permission> permissionByUsername = rolePermissionMapper.getPermissionByUserId(userId);
        permissionByUsername.forEach(permission -> {
            simpleAuthorizationInfo.addStringPermission(permission.getPermissionName());
        });
        
        return simpleAuthorizationInfo;
    }
    
    
    @Override
    public boolean isAuthenticationCachingEnabled() {
        return this.authenticationCachingEnabled && isCachingEnabled();
    }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String)authenticationToken.getPrincipal();
        //验证token是否被修改了
        if(!jwtUtil.verify(token)){
            throw new AuthenticationException("不合法身份或者身份凭证过期");
        }
        int userId = jwtUtil.getUserIdByToken(token);
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
        
        //全局使用，代替Subject.getPrincipal,因为它只能获取到token,不能获取到完整的用户信息
        PlatFormContext.currentUser.set(sysUser);
        
        return new SimpleAuthenticationInfo(token,token, sysUser.getRealName());
    }
    
  
}
